package com.vue3.blog.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vue3.blog.common.resp.BizException;
import com.vue3.blog.common.resp.PageVO;
import com.vue3.blog.common.util.PageUtil2;
import com.vue3.blog.common.util.StrUtil2;
import com.vue3.blog.domain.entity.ArticleEntity;
import com.vue3.blog.domain.entity.CategoryEntity;
import com.vue3.blog.domain.vo.CategoryVO;
import com.vue3.blog.mapper.CategoryMapper;
import com.vue3.blog.service.IArticleService;
import com.vue3.blog.service.ICategoryService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Mr.小朱同学
 * @version 1.0.0
 * @date 2025/6/12 12:26
 * @description 文章分类
 */
@Service
public class CategoryService extends ServiceImpl<CategoryMapper, CategoryEntity> implements ICategoryService {
    @Resource
    private IArticleService articleService;

    /**
     * 保存分类
     */
    @Override
    public void saveCategory(CategoryEntity category) {
        // 判断分类名称是否已经存在
        LambdaQueryWrapper<CategoryEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(CategoryEntity::getName, category.getName());
        wrapper.ne(category.getId() != null, CategoryEntity::getId, category.getId());
        long count = this.count(wrapper);
        if (count > 0) {
            throw new BizException("分类名称已经存在");
        }
        // 新增、编辑数据
        CategoryEntity entity = new CategoryEntity();
        if (category.getId() != null) {
            entity = this.getById(category.getId());
            if (null == entity) {
                throw new BizException("分类不存在");
            }
        } else {
            entity.setCreatedTime(new Date());
        }
        entity.setName(category.getName());
        entity.setRemark(StrUtil2.nvl(category.getRemark(), ""));
        entity.setUpdatedTime(new Date());
        this.saveOrUpdate(entity);
    }

    /**
     * 删除分类
     *
     * @param id 分类ID
     */
    @Override
    public void removeCategory(Long id) {
        if (null == id) {
            throw new BizException("分类不存在");
        }
        // 判断是否已经关联文章，关联则不允许删除
        LambdaQueryWrapper<ArticleEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ArticleEntity::getCategoryId, id);
        long count = articleService.count(wrapper);
        if (count > 0) {
            throw new BizException("分类已经关联文章，请先解除关联！");
        }
        this.removeById(id);
    }

    /**
     * 分类下拉列表
     */
    @Override
    public List<CategoryEntity> dropList() {
        LambdaQueryWrapper<CategoryEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.orderByDesc(CategoryEntity::getCreatedTime);
        List<CategoryEntity> entityList = this.list(wrapper);
        if (CollUtil.isEmpty(entityList)) {
            return Collections.emptyList();
        }
        return entityList;
    }

    /**
     * 分类列表
     *
     * @param name 分类名称
     */
    @Override
    public PageVO<CategoryVO> getCategoryList(String name) {
        LambdaQueryWrapper<CategoryEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StrUtil2.isNotEmpty(name), CategoryEntity::getName, name);
        wrapper.orderByDesc(CategoryEntity::getCreatedTime);
        PageUtil2.startPage();
        List<CategoryEntity> entityList = this.list(wrapper);
        if (CollUtil.isEmpty(entityList)) {
            return PageUtil2.endPage(Collections.emptyList());
        }
        Map<Long, Long> articleNumMap = new HashMap<>();
        // 查询分类关联的文章数量
        LambdaQueryWrapper<ArticleEntity> articleWrapper = Wrappers.lambdaQuery();
        articleWrapper.select(ArticleEntity::getCategoryId, ArticleEntity::getId);
        articleWrapper.in(ArticleEntity::getCategoryId, CollUtil.getFieldValues(entityList, "id"));
        List<ArticleEntity> articleList = articleService.list(articleWrapper);
        if (CollUtil.isNotEmpty(articleList)) {
            Map<Long, Long> numMap = articleList.stream().collect(Collectors.groupingBy(ArticleEntity::getCategoryId, Collectors.counting()));
            articleNumMap.putAll(numMap);
        }

        List<CategoryVO> voList = new ArrayList<>();
        entityList.forEach(ent -> {
            CategoryVO vo = new CategoryVO();
            BeanUtils.copyProperties(ent, vo);
            vo.setArticleNum(Math.toIntExact(articleNumMap.getOrDefault(ent.getId(), 0L)));
            voList.add(vo);
        });
        return PageUtil2.endPage(entityList, voList);
    }

    /**
     * 获取分类ID和名称映射关系
     */
    @Override
    public Map<Long, String> getCategoryIdAndNameMap() {
        List<CategoryEntity> entityList = dropList();
        return entityList.stream().collect(Collectors.toMap(CategoryEntity::getId, CategoryEntity::getName));
    }
}